// src/components/common/quill-rte.js
import React, {useEffect, useRef, useState} from 'react';
import {useSelector} from "react-redux";
import DOMPurify from 'dompurify';
import Quill from 'quill';
import 'quill/dist/quill.snow.css';

import {Box, Button, Paper, TextareaAutosize, Typography} from '@mui/material';
import {ArrowBack, Code, KeyboardReturn, Save, Visibility} from '@mui/icons-material';
import LoadingButton from "@mui/lab/LoadingButton";
import CircularProgress from "@mui/material/CircularProgress";

import {query as queryContent, save, uploadImage} from "../../api/common/rte";

const names = Object.freeze({
    'SCHOOL': '学校信息',
    'TEACHER': '教师信息',
    'COURSE': '课程信息',
});

const RichTextEditor = ({cat, entityId = 0, title = null, back = null}) => {

        const user = useSelector(state => state.auth.user);
        const {schoolId} = user;

        const [editor, setEditor] = useState(null);

        const [loading, setLoading] = useState(false);
        const [submitting, setSubmitting] = useState(false);

        const [preview, setPreview] = useState(false);
        const [sourceCode, setSourceCode] = useState(false);
        const [id, setId] = useState(0);
        const [htmlContent, setHtmlContent] = useState('');

        const editorRef = useRef(null);

        const fileInputRef = useRef(null);

        const handleImageSelected = (event) => {
            const [file] = event.target.files;
            if (file) {
                const formData = new FormData();
                formData.append('file', file);
                uploadImage(formData).then(data => {
                    if (data) {
                        const range = editor.getSelection();
                        editor.insertEmbed(range.index, 'image', data);
                    }
                });
            }
        };

        useEffect(() => {
            if (editor === null && editorRef.current) {
                const quill = new Quill(editorRef.current, {
                    theme: 'snow',
                    modules: {
                        toolbar: {
                            container:
                                [
                                    [{header: [1, 2, false]}],
                                    ['bold', 'italic', 'underline'],
                                    [{align: []}],
                                    [{list: 'ordered'}, {list: 'bullet'}],
                                    ['image'],
                                    ['clean'],
                                ],
                            handlers: {'image': () => fileInputRef.current.click()}
                        },
                    },
                });

                setEditor(prev => prev === null ? quill : prev);
            }

            if (editor) {
                setLoading(true);
                queryContent({id: 0, schoolId, cat, entityId, content: ''}).then(
                    data => {
                        if (data) {
                            setHtmlContent(data.content);
                            setId(data.id);
                            editor.clipboard.dangerouslyPasteHTML(data.content);
                        }
                        setLoading(false);
                    }
                );
            }
        }, [editor, schoolId, cat, entityId]);

        const handleSave = async () => {
            const contentToSave = sourceCode ? htmlContent : editor.root.innerHTML;
            if (!contentToSave) {
                return;
            }

            setSubmitting(true);
            save({id, schoolId, cat, entityId, content: DOMPurify.sanitize(contentToSave)})
                .then(() => setSubmitting(false));
        }


        const togglePreview = () => {
            setPreview(!preview);
            if (preview && sourceCode) {
                setSourceCode(false);
                editor.clipboard.dangerouslyPasteHTML(htmlContent);
            }
        };

        const toggleSourceCode = () => {
            if (!preview) {
                if (!sourceCode) {
                    setHtmlContent(editor.root.innerHTML);
                } else {
                    editor.clipboard.dangerouslyPasteHTML(htmlContent);
                }
                setSourceCode(!sourceCode);
            }
        };

        const handleSourceCodeChange = (event) => {
            setHtmlContent(event.target.value);
        };

        return (
            <Box padding={4} gap={2} flexDirection='column' display='flex'>
                <Box flexGrow={1}>

                    <Box sx={{display: 'flex', flexDirection: 'column', gap: 2, width: '100%'}}>
                        <input
                            type="file"
                            accept="image/*"
                            style={{display: 'none'}}
                            ref={fileInputRef}
                            onChange={handleImageSelected}
                        />

                        <Box display='flex' gap={2} alignItems='center'>
                            <Typography variant="h5">{names[cat]}</Typography>
                            {title && <Typography variant="body2">{title}</Typography>}
                            {loading && <CircularProgress color="inherit" size={24}/>}
                        </Box>

                        {preview && !sourceCode && (
                            <Paper className={'ql-editor'} style={{padding: '4px 12px'}} elevation={3}>
                                <div dangerouslySetInnerHTML={{__html: editor?.root.innerHTML}}/>
                            </Paper>
                        )}

                        {sourceCode && !preview &&
                            <TextareaAutosize minRows={10} value={htmlContent} onChange={handleSourceCodeChange}/>
                        }

                        <Box sx={{display: preview || sourceCode ? "none" : 'block'}}>
                            <div ref={editorRef}/>
                        </Box>

                        <Box sx={{display: 'flex', gap: 2}}>

                            {back !== null &&
                                <Button variant="contained" color="secondary" startIcon={<ArrowBack/>}
                                        onClick={back}>返回</Button>
                            }

                            <Button
                                variant="contained"
                                startIcon={preview ? <KeyboardReturn/> : <Visibility/>}
                                onClick={togglePreview}
                                disabled={sourceCode}
                            >
                                {preview ? '返回' : '预览'}
                            </Button>

                            <Button
                                variant="contained"
                                startIcon={sourceCode ? <KeyboardReturn/> : <Code/>}
                                onClick={toggleSourceCode}
                                disabled={preview}
                            >
                                {sourceCode ? '返回' : '源码'}
                            </Button>
                            <LoadingButton
                                loading={submitting} variant="contained" startIcon={<Save/>}
                                loadingIndicator={<CircularProgress color="inherit" size={24}/>}
                                onClick={handleSave}>保存
                            </LoadingButton>
                        </Box>
                    </Box>
                </Box>
            </Box>
        );
    }
;

export default RichTextEditor;
